﻿
Imports System.Text
Imports System.Management.Automation.Runspaces
Imports Client.PowerShell

Imports System.Management.Automation
Imports System.Collections.ObjectModel



Namespace PowerShell

    Public Class RunSync

        Implements IRun



        Public Sub Run(ByVal Command As String) Implements IRun.Run

            'Dim _Result = New StringBuilder
            ''.AddCommand("set-executionpolicy").AddArgument("unrestricted")
            'Dim Results = System.Management.Automation.PowerShell.Create.AddScript(Command).Invoke '(Of String)()

            'For Each Result As PSObject In Results

            '    _Result.AppendLine(Result.ToString)

            'Next

            'RaiseEvent OutputChanged(_Result.ToString)

            'RaiseEvent RunFinished()

            ' create Powershell runspace 
            Dim MyRunSpace As Runspace = RunspaceFactory.CreateRunspace()

            ' open it 
            MyRunSpace.Open()

            ' create a pipeline and feed it the script text 
            Dim MyPipeline As Pipeline = MyRunSpace.CreatePipeline()

            MyPipeline.Commands.AddScript(Command)

            ' add an extra command to transform the script output objects into nicely formatted strings 
            ' remove this line to get the actual objects that the script returns. For example, the script 
            ' "Get-Process" returns a collection of System.Diagnostics.Process instances. 
            MyPipeline.Commands.Add("Out-String")

            ' execute the script 
            Dim results As Collection(Of PSObject) = MyPipeline.Invoke()

            ' close the runspace 
            MyRunSpace.Close()

            ' convert the script result into a single string 
            Dim MyStringBuilder As New StringBuilder()

            For Each obj As PSObject In results
                MyStringBuilder.AppendLine(obj.ToString())

            Next


            RaiseEvent OutputChanged(MyStringBuilder.ToString)

            RaiseEvent RunFinished()

            ' return the results of the script that has 
            ' now been converted to text 
            'Return MyStringBuilder.ToString()


        End Sub



        Public Event OutputChanged(ByVal Output As String) Implements IRun.OutputChanged



        Public Event RunFinished() Implements IRun.RunFinished

    End Class







    Public Class RunASync

        Implements IRun





        Private _RunSpace As Runspace

        Private _PipeLine As Pipeline

        Private WithEvents _OutPut As PipelineReader(Of PSObject)



        Public Event OutPutChanged(ByVal Output As String) Implements IRun.OutputChanged



        Public Sub New()

            _RunSpace = RunspaceFactory.CreateRunspace
            '_RunSpace.RunspaceConfiguration.
            _RunSpace.Open()

        End Sub



        Public Sub Run(ByVal Command As String) Implements IRun.Run
            '_RunSpace.
            _PipeLine = _RunSpace.CreatePipeline(Command)

            _PipeLine.Input.Close()

            _OutPut = _PipeLine.Output

            _PipeLine.InvokeAsync()

        End Sub



        Private Sub _Output_DataReady(ByVal sender As Object, ByVal e As System.EventArgs) Handles _OutPut.DataReady

            Dim data = _PipeLine.Output.NonBlockingRead()

            If data.Count > 0 Then

                For Each d As PSObject In data

                    RaiseEvent OutPutChanged(d.ToString & Environment.NewLine)

                Next

            End If

            If _PipeLine.Output.EndOfPipeline Then

                RaiseEvent RunFinished()

            End If

        End Sub



        Public Event RunFinished() Implements IRun.RunFinished

    End Class




End Namespace

